﻿#region

using System;
using RuanRang.Media.Core.Common;
using RuanRang.Media.Core.Exceptions;
using RuanRang.Media.Core.Internal.DataStructures;
using RuanRang.Media.Core.Internal.Interop;

#endregion

namespace RuanRang.Media.Core.Media
{
    /// <summary>
    ///     VlcMediaMetadatas class
    /// </summary>
    public sealed class VlcMediaMetadatas
    {
        /// <summary>
        ///     The _my host media base
        /// </summary>
        private readonly BaseMedia _myHostMediaBase;

        /// <summary>
        ///     Initializes a new instance of the <see cref="VlcMediaMetadatas" /> class.
        /// </summary>
        /// <param name="mediaBase">The media base.</param>
        internal VlcMediaMetadatas(BaseMedia mediaBase)
        {
            _myHostMediaBase = mediaBase;
            _album = GetMetadata(libvlc_meta_t.libvlc_meta_Album);
            _artist = GetMetadata(libvlc_meta_t.libvlc_meta_Artist);
            _artworkURL = GetMetadata(libvlc_meta_t.libvlc_meta_ArtworkURL);
            _copyright = GetMetadata(libvlc_meta_t.libvlc_meta_Copyright);
            _date = GetMetadata(libvlc_meta_t.libvlc_meta_Date);
            _description = GetMetadata(libvlc_meta_t.libvlc_meta_Description);
            _encodedBy = GetMetadata(libvlc_meta_t.libvlc_meta_EncodedBy);
            _genre = GetMetadata(libvlc_meta_t.libvlc_meta_Genre);
            _language = GetMetadata(libvlc_meta_t.libvlc_meta_Language);
            _nowPlaying = GetMetadata(libvlc_meta_t.libvlc_meta_NowPlaying);
            _publisher = GetMetadata(libvlc_meta_t.libvlc_meta_Publisher);
            _rating = GetMetadata(libvlc_meta_t.libvlc_meta_Rating);
            _setting = GetMetadata(libvlc_meta_t.libvlc_meta_Setting);
            _title = GetMetadata(libvlc_meta_t.libvlc_meta_Title);
            _trackID = GetMetadata(libvlc_meta_t.libvlc_meta_TrackID);
            _trackNumber = GetMetadata(libvlc_meta_t.libvlc_meta_TrackNumber); 
            _url = GetMetadata(libvlc_meta_t.libvlc_meta_ArtworkURL);
        }

        #region Metadatas

        private string _album;
        /// <summary>
        ///     Gets or sets the Album metadata
        /// </summary>
        public string Album
        {
            get { return _album; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Album, value);
                _album = value;
            }
        }

        private string _artist;
        /// <summary>
        ///     Gets or sets the Artist metadata
        /// </summary>
        public string Artist
        {
            get { return _artist; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Artist, value);
                _artist = value;
            }
        }

        private string _artworkURL;
        /// <summary>
        ///     Gets or sets the ArtworkURL metadata
        /// </summary>
        public string ArtworkURL
        {
            get { return _artworkURL; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_ArtworkURL, value);
                _artworkURL = value;
            }
        }

        private string _copyright;
        /// <summary>
        ///     Gets or sets the Copyright metadata
        /// </summary>
        public string Copyright
        {
            get { return _copyright; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Copyright, value);
                _copyright = value;
            }
        }

        private string _date;
        /// <summary>
        ///     Gets or sets the Date metadata
        /// </summary>
        public string Date
        {
            get { return _date; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Date, value);
                _date = value;
            }
        }

        private string _description;
        /// <summary>
        ///     Gets or sets the Description metadata
        /// </summary>
        public string Description
        {
            get { return _description; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Description, value);
                _description = value;
            }
        }

        private string _encodedBy;
        /// <summary>
        ///     Gets or sets the EncodedBy metadata
        /// </summary>
        public string EncodedBy
        {
            get { return _encodedBy; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_EncodedBy, value);
                _encodedBy = value;
            }
        }

        private string _genre;
        /// <summary>
        ///     Gets or sets the Genre metadata
        /// </summary>
        public string Genre
        {
            get { return _genre; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Genre, value);
                _genre = value;
            }
        }

        private string _language;
        /// <summary>
        ///     Gets or sets the Language metadata
        /// </summary>
        public string Language
        {
            get { return _language; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Language, value);
                _language = value;
            }
        }

        private string _nowPlaying;
        /// <summary>
        ///     Gets or sets the NowPlaying metadata
        /// </summary>
        public string NowPlaying
        {
            get { return _nowPlaying; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_NowPlaying, value);
                _nowPlaying = value;
            }
        }

        private string _publisher;
        /// <summary>
        ///     Gets or sets the Publisher metadata
        /// </summary>
        public string Publisher
        {
            get { return _publisher; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Publisher, value);
                _publisher = value;
            }
        }

        private string _rating;
        /// <summary>
        ///     Gets or sets the Rating metadata
        /// </summary>
        public string Rating
        {
            get { return _rating; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Rating, value);
                _rating = value;
            }
        }

        private string _setting;
        /// <summary>
        ///     Gets or sets the Setting metadata
        /// </summary>
        public string Setting
        {
            get { return _setting; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Setting, value);
                _setting = value;
            }
        }

        private string _title;
        /// <summary>
        ///     Gets or sets the Title metadata
        /// </summary>
        public string Title
        {
            get { return _title; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_Title, value);
                _title = value;
            }
        }

        private string _trackID;
        /// <summary>
        ///     Gets or sets the TrackID metadata
        /// </summary>
        public string TrackID
        {
            get { return _trackID; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_TrackID, value);
                _trackID = value;
            }
        }

        private string _trackNumber;
        /// <summary>
        ///     Gets or sets the TrackNumber metadata
        /// </summary>
        public string TrackNumber
        {
            get { return _trackNumber; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_TrackNumber, value);
                _trackNumber = value;
            }
        }

        private string _url;
        /// <summary>
        ///     Gets or sets the URL metadata
        /// </summary>
        public string URL
        {
            get { return _url; }
            set
            {
                SetMetadata(libvlc_meta_t.libvlc_meta_ArtworkURL, value);
                _url = value;
            }
        }

        /// <summary>
        ///     Gets media metadata
        /// </summary>
        /// <param name="metadata">Media property</param>
        /// <returns>Metadata value</returns>
        private string GetMetadata(libvlc_meta_t metadata)
        {
            if (_myHostMediaBase.Handle == IntPtr.Zero)
            {
                return string.Empty;
            }
            if (!LibVlcMediaInterop.libvlc_media_is_parsed(_myHostMediaBase.Handle))
            {
                LibVlcMediaInterop.libvlc_media_parse(_myHostMediaBase.Handle);
            }
            try
            {
                return
                    IntPtrExtensions.ToStringAnsi(
                        LibVlcMediaInterop.libvlc_media_get_meta(_myHostMediaBase.Handle, metadata));
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        ///     Sets the metadata.
        /// </summary>
        /// <param name="metadata">The metadata.</param>
        /// <param name="value">The value.</param>
        private void SetMetadata(libvlc_meta_t metadata, string value)
        {
            if (_myHostMediaBase.Handle == IntPtr.Zero)
            {
                return;
            }
            LibVlcMediaInterop.libvlc_media_set_meta(_myHostMediaBase.Handle, metadata, value);
        }

        /// <summary>
        ///     Save the metadatas
        /// </summary>
        public void Save()
        {
            if (_myHostMediaBase.Handle == IntPtr.Zero)
            {
                return;
            }
            LibVlcMediaInterop.libvlc_media_save_meta(_myHostMediaBase.Handle);
        }
        #endregion
    }
}